package com.it.intelligent_team.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.intelligent_team.annotation.AuthCheck;
import com.it.intelligent_team.common.BaseResponse;
import com.it.intelligent_team.common.DeleteRequest;
import com.it.intelligent_team.common.ErrorCode;
import com.it.intelligent_team.common.ResultUtils;
import com.it.intelligent_team.constant.UserConstant;
import com.it.intelligent_team.exception.BusinessException;
import com.it.intelligent_team.exception.ThrowUtils;
import com.it.intelligent_team.manager.model.dto.meeting.MeetingAddRequest;
import com.it.intelligent_team.manager.model.dto.meeting.MeetingEditRequest;
import com.it.intelligent_team.manager.model.dto.meeting.MeetingQueryRequest;
import com.it.intelligent_team.manager.model.dto.meeting.MeetingUpdateRequest;
import com.it.intelligent_team.manager.model.entity.Meeting;
import com.it.intelligent_team.manager.model.entity.User;
import com.it.intelligent_team.manager.model.vo.MeetingVO;
import com.it.intelligent_team.poi.common.utils.poi.ExcelUtil;
import com.it.intelligent_team.service.MeetingService;
import com.it.intelligent_team.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 会议接口
 *
 */
@RestController
@RequestMapping("/meeting")
@Slf4j
public class MeetingController {

    @Resource
    private MeetingService meetingService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建会议
     *
     * @param meetingAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addMeeting(@RequestBody MeetingAddRequest meetingAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(meetingAddRequest == null, ErrorCode.PARAMS_ERROR);
        // todo 在此处将实体类和 DTO 进行转换
        Meeting meeting = new Meeting();
        BeanUtils.copyProperties(meetingAddRequest, meeting);
        // 数据校验
        meetingService.validMeeting(meeting, true);
        // todo 填充默认值
        User loginUser = userService.getLoginUser(request);
        meeting.setUserId(loginUser.getId());
        // 写入数据库
        boolean result = meetingService.save(meeting);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 返回新写入的数据 id
        long newMeetingId = meeting.getId();
        return ResultUtils.success(newMeetingId);
    }

    /**
     * 删除会议
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteMeeting(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        long id = deleteRequest.getId();
        // 判断是否存在
        Meeting oldMeeting = meetingService.getById(id);
        ThrowUtils.throwIf(oldMeeting == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可删除
        if (!oldMeeting.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = meetingService.removeById(id);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }



    /**
     * 更新会议（仅管理员可用）
     *
     * @param meetingUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateMeeting(@RequestBody MeetingUpdateRequest meetingUpdateRequest) {
        if (meetingUpdateRequest == null || meetingUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // todo 在此处将实体类和 DTO 进行转换
        Meeting meeting = new Meeting();
        BeanUtils.copyProperties(meetingUpdateRequest, meeting);
        // 数据校验
        meetingService.validMeeting(meeting, false);
        // 判断是否存在
        long id = meetingUpdateRequest.getId();
        Meeting oldMeeting = meetingService.getById(id);
        ThrowUtils.throwIf(oldMeeting == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        boolean result = meetingService.updateById(meeting);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 根据 id 获取会议（封装类）
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<MeetingVO> getMeetingVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Meeting meeting = meetingService.getById(id);
        ThrowUtils.throwIf(meeting == null, ErrorCode.NOT_FOUND_ERROR);
        // 获取封装类
        return ResultUtils.success(meetingService.getMeetingVO(meeting, request));
    }

    /**
     * 分页获取会议列表（仅管理员可用）
     *
     * @param meetingQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Meeting>> listMeetingByPage(@RequestBody MeetingQueryRequest meetingQueryRequest) {
        long current = meetingQueryRequest.getCurrent();
        long size = meetingQueryRequest.getPageSize();
        // 查询数据库
        Page<Meeting> meetingPage = meetingService.page(new Page<>(current, size),
                meetingService.getQueryWrapper(meetingQueryRequest));
        return ResultUtils.success(meetingPage);
    }

    /**
     * 分页获取会议列表（封装类）
     *
     * @param meetingQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<MeetingVO>> listMeetingVOByPage(@RequestBody MeetingQueryRequest meetingQueryRequest,
                                                               HttpServletRequest request) {
        long current = meetingQueryRequest.getCurrent();
        long size = meetingQueryRequest.getPageSize();
        // 查询数据库
        Page<Meeting> meetingPage = meetingService.page(new Page<>(current, size),
                meetingService.getQueryWrapper(meetingQueryRequest));
        // 获取封装类
        return ResultUtils.success(meetingService.getMeetingVOPage(meetingPage, request));
    }

    /**
     * 分页获取当前登录用户创建的会议列表
     *
     * @param meetingQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<MeetingVO>> listMyMeetingVOByPage(@RequestBody MeetingQueryRequest meetingQueryRequest,
                                                                 HttpServletRequest request) {
        ThrowUtils.throwIf(meetingQueryRequest == null, ErrorCode.PARAMS_ERROR);
        // 补充查询条件，只查询当前登录用户的数据
        User loginUser = userService.getLoginUser(request);
        long current = meetingQueryRequest.getCurrent();
        long size = meetingQueryRequest.getPageSize();
        // 查询数据库
        Page<Meeting> meetingPage = meetingService.page(new Page<>(current, size),
                meetingService.getQueryWrapper(meetingQueryRequest));
        // 获取封装类
        return ResultUtils.success(meetingService.getMeetingVOPage(meetingPage, request));
    }

    /**
     * 编辑会议（给用户使用）
     *
     * @param meetingEditRequest
     * @param request
     * @return
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editMeeting(@RequestBody MeetingEditRequest meetingEditRequest, HttpServletRequest request) {
        if (meetingEditRequest == null || meetingEditRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // todo 在此处将实体类和 DTO 进行转换
        Meeting meeting = new Meeting();
        BeanUtils.copyProperties(meetingEditRequest, meeting);
        // 数据校验
        meetingService.validMeeting(meeting, false);
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        long id = meetingEditRequest.getId();
        Meeting oldMeeting = meetingService.getById(id);
        ThrowUtils.throwIf(oldMeeting == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可编辑
        if (!oldMeeting.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = meetingService.updateById(meeting);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }


   /**
    * excel 导入会议数据
    * @param file
    * @return
    * @throws Exception
    */
    @PostMapping("/importData")
    public BaseResponse<Meeting> importData(MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return ResultUtils.error("上传的文件为空");
        }

        String fileName = file.getOriginalFilename();
        if (!fileName.matches("(?i).+\\.(xls|xlsx)$")) {
            return ResultUtils.error("请上传Excel文件（.xls或.xlsx格式）");
        }

        try (InputStream is = new BufferedInputStream(file.getInputStream())) {
            // 验证文件类型
            FileMagic fileMagic = FileMagic.valueOf(is);
            if (fileMagic != FileMagic.OLE2 && fileMagic != FileMagic.OOXML) {
                return ResultUtils.error("文件格式不支持，请上传有效的Excel文件");
            }

            // 重置流
            is.reset();

            // 处理Excel
            ExcelUtil<Meeting> util = new ExcelUtil<>(Meeting.class);
            List<Meeting> meetingList = util.importExcel(is);
            meetingService.saveBatch(meetingList, 100);
            return ResultUtils.success();
        } catch (Exception e) {
            log.error("Excel导入失败: {}", e.getMessage(), e);
            return ResultUtils.error("Excel导入失败: " + e.getMessage());
        }

       /* // 读取一下数据
        ExcelUtil<Meeting> util = new ExcelUtil<>(Meeting.class);
        List<Meeting> meetingList = util.importExcel(file.getInputStream());
        // 对会议计划详情进行修改一下
        meetingList = meetingList.stream().map(meeting -> {


        return meeting;
        }).collect(Collectors.toList());
        meetingService.saveBatch(meetingList, 100);
        return ResultUtils.success();*/
    }

    /**
     * excel 导出会议列表
     * @param response
     * @param meeting
     */
      @PostMapping("/export")
      public void export(HttpServletResponse response, Meeting meeting) {
        List<Meeting> list = meetingService.getBaseMapper().selectList(Wrappers.lambdaQuery(meeting));
        ExcelUtil<Meeting> util = new ExcelUtil<>(Meeting.class);
        util.exportExcel(response, list, "会议数据");
      }


    /**
     * 批量删除会议
     *
     * @param ids ID数组
     * @return 是否成功
     */
     @DeleteMapping("/remove/{ids}")
     public BaseResponse<Boolean> removeMeetings(@PathVariable Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = meetingService.removeByIds(ids);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success();
     }


     /**
     * 批量查询会议
     *
     * @param ids ID数组
     * @return 会议分页列表
     */
     @GetMapping("/list/{ids}")
     public BaseResponse<Page<MeetingVO>> listMeetings(@PathVariable Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<Meeting> meetingList = meetingService.listByIds(ids);
        Page<MeetingVO> meetingVOPage = new Page<>(1, meetingList.size());
        List<MeetingVO> meetingVOList = meetingList.stream()
        .map(meeting -> meetingService.getMeetingVO(meeting, null))
        .collect(Collectors.toList());
        meetingVOPage.setRecords(meetingVOList);
        meetingVOPage.setTotal(meetingList.size());
         return ResultUtils.success(meetingVOPage);
         }

          /**
           * 批量插入会议
           *
           * @param meetingList 会议列表
           * @return 是否成功
           */
     @PostMapping("/batch")
     public BaseResponse<Boolean> batchAddMeeting(@RequestBody List<MeetingAddRequest> meetingList) {
        if (CollUtil.isEmpty(meetingList)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<Meeting> meetingEntityList = meetingList.stream().map(meetingAddRequest -> {
        Meeting meeting = new Meeting();
        BeanUtils.copyProperties(meetingAddRequest, meeting);
        return meeting;
        }).collect(Collectors.toList());
        boolean result = meetingService.saveBatch(meetingEntityList);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success();
     }
     // endregion
}
